package com.prosay.mvc.util;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

public class ClassScanner {
	/**
	 * 包扫描的工具类 扫描某个包下面的所有类
	 * 
	 * @param base
	 *            基础包
	 * @return Map<类名,类的class实例>
	 */
	public static Map<String, Class<?>> scannerClass(String base) {
		Map<String, Class<?>> result = new HashMap<String, Class<?>>();
		// com.prosay.mvc
		// 通过包名将.替换成/
		base = base.replace(".", "/");
		try {
			Enumeration<URL> dirs = Thread.currentThread().getContextClassLoader().getResources(base);
			String rootPath = Thread.currentThread().getContextClassLoader().getResource(base).getPath();

			if (rootPath != null) {
				rootPath = rootPath.substring(rootPath.lastIndexOf(base));
			}
			System.out.println(rootPath);
			while (dirs.hasMoreElements()) {
				URL url = dirs.nextElement();
				// 根据url判断是否文件对象
				if (url.getProtocol().equals("file")) {
					File file = new File(url.getPath().substring(1));
					scannerFile(file, rootPath, result);
				}
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return result;
	}

	private static void scannerFile(File file, String rootPath, Map<String, Class<?>> classes) {
		// 拿到file里面的所有文件对象文件夹为空listFiles会返回null对象
		File[] files = file.listFiles();
		for (int i = 0; files != null && i < files.length; i++) {
			File fi = files[i];
			if (fi.isDirectory()) {// 判断是否为文件夹
				// 递归查找
				scannerFile(fi, rootPath + fi.getName() + "/", classes);
			} else {
				// 获取真实路径
				String path = fi.getAbsolutePath();
				// 判断是否以.class结尾
				if (path.endsWith(".class")) {
					// 把\\替换成/
					path = path.replace("\\", "/");
					// 完整的类路径com.prosay.mvc.IndexConytroller
					String className = rootPath
							+ path.subSequence(path.lastIndexOf("/") + 1, path.lastIndexOf(".class"));
					// 把/换回.
					className = className.replace("/", ".");
					try {
						classes.put(className, Class.forName(className));
					} catch (ClassNotFoundException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}

	public static void main(String[] args) {
		// 测试
		scannerClass("com.prosay.mvc");
	}
}
